module Sparkle
  module Refreshable

    def self.included(base)
      base.extend ClassMethods
      base.class_eval do
        class_inheritable_accessor :_sparkle_cache_refresh_method
        attr_accessor :_sparkle_cached_
        attr_accessor :_sparkle_cache_key_
      end
    end

    def _sparkle_refresh!
      self.send self.class._sparkle_cache_refresh_method
      Rails.cache.write(self._sparkle_cache_key_, self)
    end

    module ClassMethods

      def sparkle_refresh_method method_name
        self._sparkle_cache_refresh_method = method_name.to_sym
      end

      def sparkle_fetch(*args)
        key = _sparkle_cache_key(*args)
        if object = Rails.cache.read(key)
          begin
            object._sparkle_cached_ = true
          rescue TypeError => e
            object = object.dup
            object._sparkle_cached_ = true
          end
        else
          object = new(*args)
          object.send object.class._sparkle_cache_refresh_method
          object._sparkle_cached_ = false
          object._sparkle_cache_key_ = key
          Rails.cache.write(key, object)
        end
        object
      end

      private

      def _sparkle_cache_key(*args)
        Digest::SHA1.hexdigest("#{name}:#{args.join('|')}")
      end

    end
  end
end
